# Python 迭代器
# 迭代器是一个可以记住遍历的位置的对象。
# 迭代器对象从集合的第一个元素开始访问，直到所有的元素被访问完结束。迭代器只能往前不会后退。
# 迭代器有两个基本的方法：iter() 和 next()。
# iter() 方法返回一个迭代器对象，该对象可以遍历序列的元素。
# next() 方法用于访问迭代器的下一个元素，如果没有更多的元素，则抛出 StopIteration 异常。
# 迭代器只能用于一次性遍历序列，因为迭代器只能往前不会后退。
# 迭代器是惰性计算的，只有在需要返回下一个元素时它才会计算。
# 迭代器可以节省内存，因为集合中的元素不会一次性加载到内存中。
# 迭代器可以用于各种数据结构，如列表、字典、文件、字符串等。

# 迭代器与可迭代对象
# 迭代器是可迭代对象，但不是所有可迭代对象都是迭代器。
# 可迭代对象是指可以返回一个迭代器的对象，如列表、字典、字符串等。
# 字符串、字典、元组等不可变对象是可迭代对象，但不是迭代器。
# 字符串、字典、元组等不可变对象只能被迭代一次。
# 可变对象如列表、字典等是可迭代对象，也是迭代器。
# 可变对象可以被迭代多次。

# 验证是否是可迭代对象
from collections.abc import Iterable   # 导入 Iterable 基类

def is_iterable(obj):
    return isinstance(obj, Iterable)   # 判断是否是 Iterable 类型
# 测试
print(is_iterable([1, 2, 3]))  # True
print(is_iterable("hello"))  # True
print(is_iterable(123))  # False
print(is_iterable({1: "a", 2: "b"}))  # True
print(is_iterable((1, 2, 3)))  # True


# 1. 列表的迭代器
# 列表是最常见的迭代对象，可以使用列表的 iter() 方法获取一个迭代器对象。
numbers = [1, 2, 3, 4, 5]
# 获取迭代器对象
numbers_iter = iter(numbers)
# 遍历迭代器对象
while True:
    try:
        # 获取下一个元素
        num = next(numbers_iter)
        print(num)
    except StopIteration:
        # 遇到 StopIteration 异常退出循环
        break
# 输出结果：
# 1
# 2
# 3
# 4
# 5

# 2. 字典的迭代器
# 字典也是可迭代对象，可以使用字典的 items() 方法获取一个迭代器对象。
person = {"name": "风清影竹", "age": 25, "city": "广州"}
# 获取迭代器对象
person_iter = iter(person.items())
# 遍历迭代器对象
while True:
    try:
        # 获取下一个元素
        item = next(person_iter)
        print(item)
    except StopIteration:
        # 遇到 StopIteration 异常退出循环
        break
# 输出结果：
# ('name', '风清影竹')
# ('age', 25)
# ('city', '广州')

# 3. 字符串的迭代器
# 字符串也是可迭代对象，可以使用字符串的 iter() 方法获取一个迭代器对象。
s = "fuck you"
# 获取迭代器对象
s_iter = iter(s)
# 遍历迭代器对象
while True:
    try:
        # 获取下一个元素
        c = next(s_iter)
        print(c)
    except StopIteration:
        # 遇到 StopIteration 异常退出循环
        break
# 输出结果：
# f
# u
# c
# k
#
# y
# o
# u

# 4. 元组的迭代器
# 元组也是可迭代对象，可以使用元组的 iter() 方法获取一个迭代器对象。
t = (1, 2, 3, 4, 5)
# 获取迭代器对象
t_iter = iter(t)
# 遍历迭代器对象
while True:
    try:
        # 获取下一个元素
        num = next(t_iter)
        print(num)
    except StopIteration:
        # 遇到 StopIteration 异常退出循环
        break
# 输出结果：
# 1
# 2
# 3
# 4
# 5
